﻿// 1371. 每个元音包含偶数次的最长子字符串.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <unordered_map>

using namespace std;
/*
https://leetcode.cn/problems/find-the-longest-substring-containing-vowels-in-even-counts/description/

给你一个字符串 s ，请你返回满足以下条件的最长子字符串的长度：每个元音字母，
即 'a'，'e'，'i'，'o'，'u' ，在子字符串中都恰好出现了偶数次。


示例 1：
输入：s = "eleetminicoworoep"
输出：13
解释：最长子字符串是 "leetminicowor" ，它包含 e，i，o 各 2 个，以及 0 个 a，u 。

示例 2：
输入：s = "leetcodeisgreat"
输出：5
解释：最长子字符串是 "leetc" ，其中包含 2 个 e 。

示例 3：
输入：s = "bcbcbc"
输出：6
解释：这个示例中，字符串 "bcbcbc" 本身就是最长的，因为所有的元音 a，e，i，o，u 都出现了 0 次。


提示：
1 <= s.length <= 5 x 10^5
s 只包含小写英文字母。
*/


/*
用二进制记录 元音字母出现的状态
当前索引减去 最早出现的相同的状态,就是一段元音字母出现偶数次的长度(二进制异或 出现偶数次就是0 )
*/
class Solution {
public:
    int findTheLongestSubstring(string s) {
        int mask = 0;
        unordered_map<char, int> mm;
        mm['a'] = 1;
        mm['e'] = 1 << 1;
        mm['i'] = 1 << 2;
        mm['o'] = 1 << 3;
        mm['u'] = 1 << 4;
        int ans = 0;

        unordered_map<int, int>  hashm; hashm[0] = -1;
        for (int i = 0; i < s.size(); i++) {
            if (mm[s[i]] != 0) {
                mask ^= mm[s[i]];
            }
            if (hashm.count(mask) == 0) { hashm[mask] = s.size()+10; }
            ans = max(ans, i - hashm[mask]);
            hashm[mask] = min(i, hashm[mask]);
        }
        
        return ans;
    }
};
 

int main()
{
    Solution s;
    s.findTheLongestSubstring("leetcodeisgreat");
}